package co.fitstart.admin.entity.search;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.demo2do.core.persistence.support.Filter;
import com.demo2do.core.persistence.support.Order;
import com.demo2do.core.persistence.support.QueryBuilder;

import co.fitstart.entity.course.CourseType;
import co.fitstart.entity.course.round.RoundStatus;
import co.fitstart.entity.course.schedule.ScheduleStatus;
import co.fitstart.entity.principal.Principal;
import co.fitstart.entity.site.Site;
import co.fitstart.entity.user.Student;
import co.fitstart.entity.utils.DateFormatUtils;
import co.fitstart.entity.utils.DateUtils;

/**
 * 
 * @author haiyan_xiao
 *
 */
public class SatisfactionSurveySearch implements QueryBuilder {

    private Site site;

    private Principal coach;

    private Date oneMonthAgo;

    /** 有未完成问卷或最近两个月内有做过问卷的学员 */
    private List<Student> excludedStudents;

    private Filter filter;

    public SatisfactionSurveySearch() {
        
    }

    /*
     * (non-Javadoc)
     * @see com.demo2do.core.persistence.support.QueryBuilder#getPreparedFilter(boolean)
     */
    public Filter getPreparedFilter(boolean refresh) {
        oneMonthAgo = DateUtils.parseDate(DateFormatUtils.format(DateUtils.addMonths(new Date(), -1), "yyyy-MM-dd"), "yyyy-MM-dd");
        List<CourseType> courseTypes = Arrays.asList(new CourseType[]{CourseType.INDIVIDUAL, CourseType.SPECIAL, CourseType.POSTURE, CourseType.YEAR});
        List<RoundStatus> courseStatuss = Arrays.asList(new RoundStatus[]{RoundStatus.READY});
        
        if(filter == null || refresh) {
            filter = new Filter().addEquals("schedule.disabled", false)
                                 .addEquals("schedule.scheduleStatus", ScheduleStatus.FINISH)
                                 .addGreaterThan("schedule.occurDate", oneMonthAgo)
                                 .addEquals("schedule.courseRound.disabled", false)
                                 .addEquals("schedule.courseRound.course.experience", false)
                                 .addEquals("schedule.courseRound.course.give", false)
                                 .addSentence("schedule.courseRound.courseType IN (:courseTypes)", "courseTypes", courseTypes)
                                 .addSentence("schedule.courseRound.courseStatus IN (:courseStatuss)", "courseStatuss", courseStatuss)
                                 .addEquals("schedule.courseRound.site", site)
                                 .addEquals("schedule.courseRound.coach", coach)
                                 .addSentence("schedule.courseRound.student NOT IN (:students)", "students", excludedStudents);
        }
        return filter;
    }

    /*
     * (non-Javadoc)
     * @see com.demo2do.core.persistence.support.QueryBuilder#getOrder()
     */
    public Order getOrder() {
        return null;
    }

    /*
     * (non-Javadoc)
     * @see com.demo2do.core.persistence.support.QueryBuilder#buildSentenceTemplate()
     */
    public String buildSentenceTemplate() {
        return "SELECT new co.fitstart.admin.entity.report.CourseScheduleCount(schedule.courseRound,COUNT(*)) FROM CourseSchedule schedule" + getPreparedFilter(false).getWhereSentence() + " GROUP BY schedule.courseRound";
    }

    /*
     * (non-Javadoc)
     * @see com.demo2do.core.persistence.support.QueryBuilder#buildParameters()
     */
    public Map<String, Object> buildParameters() {
        return getPreparedFilter(false).getParameters();
    }

    /**
     * @return the site
     */
    public Site getSite() {
        return site;
    }

    /**
     * @param site the site to set
     */
    public void setSite(Site site) {
        this.site = site;
    }

    /**
     * @return the coach
     */
    public Principal getCoach() {
        return coach;
    }

    /**
     * @param coach the coach to set
     */
    public void setCoach(Principal coach) {
        this.coach = coach;
    }

    /**
     * @return the oneMonthAgo
     */
    public Date getOneMonthAgo() {
        return oneMonthAgo;
    }

    /**
     * @param oneMonthAgo the oneMonthAgo to set
     */
    public void setOneMonthAgo(Date oneMonthAgo) {
        this.oneMonthAgo = oneMonthAgo;
    }

    /**
     * @return the excludedStudents
     */
    public List<Student> getExcludedStudents() {
        return excludedStudents;
    }

    /**
     * @param excludedStudents the excludedStudents to set
     */
    public void setExcludedStudents(List<Student> excludedStudents) {
        this.excludedStudents = excludedStudents;
    }

    /**
     * @return the filter
     */
    public Filter getFilter() {
        return filter;
    }

    /**
     * @param filter the filter to set
     */
    public void setFilter(Filter filter) {
        this.filter = filter;
    }
}
